package main

import (
	"context"
	"embed"
	// "io"
	"path/filepath"
	"io/fs"
	"log"
	"net/http"
	"os"
	"strings"

	"backend/database"
	"backend/handler"

	"gorm.io/gorm"
)

//go:embed static/*
var content embed.FS

// pathParamKey 用于在请求上下文中存储路径参数的键
type pathParamKey string

// SetPathParam 设置路径参数到请求上下文中
func SetPathParam(r *http.Request, key, value string) *http.Request {
	ctx := r.Context()
	params, _ := ctx.Value(pathParamKey("params")).(map[string]string)
	if params == nil {
		params = make(map[string]string)
	}
	params[key] = value
	return r.WithContext(context.WithValue(ctx, pathParamKey("params"), params))
}

// SetupRouter 设置API路由
func SetupRouter(db *gorm.DB) *http.ServeMux {
	// 创建标准库的ServeMux
	mux := http.NewServeMux()

	// 创建处理程序
	h := handler.NewHandler(db)

	// 创建CORS中间件
	corsMiddleware := func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			w.Header().Set("Access-Control-Allow-Origin", "*")
			w.Header().Set("Access-Control-Allow-Credentials", "true")
			w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
			w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")

			if r.Method == "OPTIONS" {
				w.WriteHeader(204)
				return
			}

			next.ServeHTTP(w, r)
		})
	}

	// 知识条目相关路由
	mux.Handle("/api/knowledge", corsMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch r.Method {
		case http.MethodGet:
			h.ListKnowledge(w, r)
		case http.MethodPost:
			h.CreateKnowledge(w, r)
		default:
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		}
	})))

	mux.Handle("/api/knowledge/search", corsMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method == http.MethodGet {
			h.SearchKnowledge(w, r)
		} else {
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		}
	})))

	mux.Handle("/api/knowledge/", corsMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// 提取ID参数
		path := r.URL.Path
		id := strings.TrimPrefix(path, "/api/knowledge/")

		// 设置ID参数到请求上下文
		r = SetPathParam(r, "id", id)

		switch r.Method {
		case http.MethodGet:
			h.GetKnowledge(w, r)
		case http.MethodPut:
			h.UpdateKnowledge(w, r)
		case http.MethodDelete:
			h.DeleteKnowledge(w, r)
		default:
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		}
	})))

	// 分类相关路由
	mux.Handle("/api/category", corsMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch r.Method {
		case http.MethodGet:
			h.ListCategories(w, r)
		case http.MethodPost:
			h.CreateCategory(w, r)
		default:
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		}
	})))

	mux.Handle("/api/category/", corsMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// 提取ID参数
		path := r.URL.Path
		id := strings.TrimPrefix(path, "/api/category/")

		// 设置ID参数到请求上下文
		r = SetPathParam(r, "id", id)

		switch r.Method {
		case http.MethodGet:
			h.GetCategory(w, r)
		case http.MethodPut:
			h.UpdateCategory(w, r)
		case http.MethodDelete:
			h.DeleteCategory(w, r)
		default:
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		}
	})))

	// 标签相关路由
	mux.Handle("/api/tag", corsMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch r.Method {
		case http.MethodGet:
			h.ListTags(w, r)
		case http.MethodPost:
			h.CreateTag(w, r)
		default:
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		}
	})))

	mux.Handle("/api/tag/", corsMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// 提取ID参数
		path := r.URL.Path
		id := strings.TrimPrefix(path, "/api/tag/")

		// 设置ID参数到请求上下文
		r = SetPathParam(r, "id", id)

		switch r.Method {
		case http.MethodGet:
			h.GetTag(w, r)
		case http.MethodPut:
			h.UpdateTag(w, r)
		case http.MethodDelete:
			h.DeleteTag(w, r)
		default:
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		}
	})))

	// 添加前端静态文件服务
	staticFS, err := fs.Sub(content, "static")
	if err != nil {
		log.Fatalf("无法获取static子目录: %v", err)
	}
	fileServer := http.FileServer(http.FS(staticFS))
	mux.Handle("/", fileServer)

	// 为静态文件创建一个处理函数，处理SPA路由
	// mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	// 	// 尝试提供静态文件
	// 	path := r.URL.Path

	// 	// 检查文件是否存在
	// 	_, err := staticFS.Open(strings.TrimPrefix(path, "/"))
	// 	if err != nil && !os.IsNotExist(err) {
	// 		http.Error(w, "内部服务器错误", http.StatusInternalServerError)
	// 		return
	// 	}

	// 	// 如果文件不存在且不是API请求，则返回index.html（支持SPA路由）
	// 	if os.IsNotExist(err) && !strings.HasPrefix(path, "/api/") {
	// 		indexFile, err := staticFS.Open("index.html")
	// 		if err != nil {
	// 			http.Error(w, "找不到index.html", http.StatusInternalServerError)
	// 			return
	// 		}
	// 		defer indexFile.Close()

	// 		stat, err := indexFile.Stat()
	// 		if err != nil {
	// 			http.Error(w, "无法获取index.html信息", http.StatusInternalServerError)
	// 			return
	// 		}

	// 		http.ServeContent(w, r, "index.html", stat.ModTime(), indexFile.(io.ReadSeeker))
	// 		return
	// 	}

	// 	// 提供静态文件
	// 	fileServer.ServeHTTP(w, r)
	// }))

	return mux
}

func main() {
	// 获取程序所在目录
	exePath, err := os.Executable()
	if err != nil {
		log.Fatalf("Failed to get executable path: %v", err)
	}
	exeDir := filepath.Dir(exePath)

	// 构建数据库文件的完整路径
	dbPath := filepath.Join(exeDir, "knowledge.db")

	// 初始化数据库
	db, err := database.InitDB(dbPath)
	if err != nil {
		log.Fatalf("Failed to initialize database: %v", err)
	}else{
		log.Println("Database initialized successfully")
	}

	// 设置路由
	r := SetupRouter(db)

	// 启动服务器
	log.Println("Server is running on http://localhost:8080")
	if err := http.ListenAndServe(":8080", r); err != nil {
		log.Fatalf("Failed to start server: %v", err)
	}
}
